package com.cloudsea.yunhaistores.service.impl;

import cn.hutool.core.lang.Snowflake;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cloudsea.yunhaistores.dto.SubmitOrderDTO;
import com.cloudsea.yunhaistores.entity.*;
import com.cloudsea.yunhaistores.mapper.*;
import com.cloudsea.yunhaistores.service.OrderService;
import com.cloudsea.yunhaistores.vo.PaymentQRCodeVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class OrderServiceImpl implements OrderService {

    // 注入所有需要的Mapper
    @Autowired private SkusMapper skusMapper;
    @Autowired private SpusMapper spusMapper;
    @Autowired private TablesMapper tablesMapper; // 确保已注入
    @Autowired private PaymentOrdersMapper paymentOrdersMapper;
    @Autowired private OrderItemsMapper orderItemsMapper;
    @Autowired private StoresMapper storesMapper;

    // 注入所需的服务和工具
    @Autowired private StringRedisTemplate redisTemplate;
    @Autowired private Snowflake snowflake;

    private static final String CART_KEY_PREFIX = "cart:";

    @Override
    @Transactional // 开启数据库事务，确保所有操作要么全部成功，要么全部失败
    public PaymentQRCodeVO submitOrder(SubmitOrderDTO dto) {
        String cartKey = CART_KEY_PREFIX + dto.getSessionId();

        // 步骤1: 从Redis中获取购物车的所有内容
        Map<Object, Object> cartEntries = redisTemplate.opsForHash().entries(cartKey);
        if (CollectionUtils.isEmpty(cartEntries)) {
            throw new RuntimeException("购物车是空的，无法下单");
        }

        // 步骤2: 批量查询所有涉及的SKU和SPU信息，用于后续校验和计算
        List<Long> skuIds = cartEntries.keySet().stream().map(k -> Long.parseLong((String) k)).collect(Collectors.toList());
        List<Skus> skuList = skusMapper.selectBatchIds(skuIds);

        if (skuList.size() != skuIds.size()) {
            throw new RuntimeException("购物车中包含已失效的商品规格，请刷新菜单后重试");
        }
        Map<Long, Skus> skuMap = skuList.stream().collect(Collectors.toMap(Skus::getId, sku -> sku));
        List<Long> spuIds = skuList.stream().map(Skus::getSpuId).distinct().collect(Collectors.toList());
        Map<Long, Spus> spuMap = spusMapper.selectBatchIds(spuIds).stream().collect(Collectors.toMap(Spus::getId, spu -> spu));

        // 步骤3: 在后端进行最终的安全校验和价格计算
        long totalAmount = 0L;
        for (Map.Entry<Object, Object> entry : cartEntries.entrySet()) {
            Long skuId = Long.parseLong((String) entry.getKey());
            int quantity = Integer.parseInt((String) entry.getValue());
            Skus sku = skuMap.get(skuId);
            if (sku.getStock() < quantity) {
                throw new RuntimeException("商品 [" + sku.getSkuName() + "] 库存不足，仅剩" + sku.getStock() + "件");
            }
            totalAmount += sku.getPrice() * quantity;
        }

        // 步骤4: 创建主订单 (payment_orders)
        PaymentOrders order = new PaymentOrders();
        long orderId = snowflake.nextId();
        order.setId(orderId);
        order.setOrderNo("PO" + orderId);
        order.setTotalAmount(totalAmount);
        order.setOrderType(dto.getOrderType());
        order.setDescription(dto.getRemarks());
        order.setPayStatus(0); // 待支付
        order.setFulfillmentStatus(0); // 待处理
        order.setCreatedAt(LocalDateTime.now());
        // 从任意一个SPU中获取 storeId
        Long storeId = spuMap.values().iterator().next().getStoreId();
        order.setStoreId(storeId);

        // 根据 storeId 查询出门店信息
        Stores store = storesMapper.selectById(storeId);
        if (store == null) {
            throw new RuntimeException("数据异常：找不到订单所属的门店信息");
        }

        // 从门店信息中获取 merchantId 并设置到订单中
        order.setMerchantId(store.getMerchantId());
        // 在创建订单时，先通过 sessionId 查询桌台信息
        QueryWrapper<Tables> tableQueryWrapper = new QueryWrapper<>();
        tableQueryWrapper.eq("current_session_id", dto.getSessionId());
        Tables table = tablesMapper.selectOne(tableQueryWrapper);

        // 如果找到了桌台，就把tableId存入订单
        if (table != null) {
            order.setTableId(table.getId());
        }
        paymentOrdersMapper.insert(order);

        // 步骤5: 创建订单详情 (order_items) 并扣减库存
        for (Map.Entry<Object, Object> entry : cartEntries.entrySet()) {
            Long skuId = Long.parseLong((String) entry.getKey());
            int quantity = Integer.parseInt((String) entry.getValue());
            Skus sku = skuMap.get(skuId);
            Spus spu = spuMap.get(sku.getSpuId());

            OrderItems orderItem = new OrderItems();
            orderItem.setId(snowflake.nextId());
            orderItem.setOrderId(orderId);
            orderItem.setSkuId(skuId);
            orderItem.setSpuName(spu.getSpuName());
            orderItem.setSkuName(sku.getSkuName());
            orderItem.setSkuPrice(sku.getPrice());
            orderItem.setQuantity(quantity);
            orderItemsMapper.insert(orderItem);

            int affectedRows = skusMapper.decreaseStock(skuId, quantity);
            if (affectedRows == 0) {
                throw new RuntimeException("扣减库存失败，商品 [" + sku.getSkuName() + "] 可能已被抢购一空，请重新下单");
            }
        }

        // 步骤6: 订单创建成功，清空Redis中的购物车
        redisTemplate.delete(cartKey);

        // 步骤7: 【新方案】更新桌台状态为“已下单/锁定”
        // 复用上面已经查询出来的 table 对象
        if (table != null) {
            if (table.getStatus() == 1) { // 仅当桌台是“使用中”时才更新
                table.setStatus(2); // 状态更新为 2:已下单/锁定
                table.setUpdatedAt(LocalDateTime.now());
                tablesMapper.updateById(table);
            }
        }

        // 步骤8: 模拟返回支付凭证
        String codeUrl = "http://your-domain.com/pay?orderNo=" + order.getOrderNo();
        PaymentQRCodeVO vo = new PaymentQRCodeVO();
        vo.setCodeUrl(codeUrl);
        vo.setOrderNo(order.getOrderNo());
        return vo;
    }
}
